home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / General / DR1.#1 PPC C⁄C++ ƒ / C++ Runtime ƒ / New.cp < prev    next >
Text File  |  1993-12-06  |  6KB  |  214 lines

  1. /************************************************************************/
  2. /*    Project...:    Standard C++ Library                                    */
  3. /*    Name......:    New.cp                                                    */
  4. /*    Purpose...:    standard C++ library                                    */
  5. /*  Copyright.: ©Copyright 1993 by metrowerks inc. All rights reserved. */
  6. /************************************************************************/
  7.  
  8. #include <new.h>
  9. #include <Memory.h>
  10.  
  11. #define SIMPLENEW    0            //    call NewPtr(...)/DisposPtr(...) if != 0
  12.  
  13.     /*    prototypes    */
  14.  
  15. void _set_newpoolsize(size_t);
  16. void _set_newnonptrmax(size_t);
  17. char _prealloc_newpool(size_t);
  18.  
  19. void *__new_hdl(size_t size);
  20. void __del_hdl(void *hdl);
  21.  
  22.  
  23. static void (*new_handler)();
  24.  
  25. extern void (*set_new_handler (void (*new_new_handler) ())) ()
  26. {
  27.     void (*old_new_handler)() = new_handler;
  28.     new_handler = new_new_handler;
  29.     return old_new_handler;
  30. }
  31.  
  32. #if SIMPLENEW
  33.  
  34. /************************************************************************/
  35. /*    Purpose..:     Allocate memory                                            */
  36. /*    Input....:    size of memory to allocate                                */
  37. /*    Return...:    pointer to memory or 0L                                    */
  38. /************************************************************************/
  39. void *operator new(size_t size)
  40. {
  41.     void *ptr;
  42.  
  43.     while((ptr=NewPtr(size))==NULL)
  44.     {
  45.         if(new_handler) new_handler(); else return(NULL);
  46.     }
  47.     return(ptr);
  48. }
  49.  
  50. /************************************************************************/
  51. /*    Purpose..:     Dispose memory                                            */
  52. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  53. /*    Return...:    ---                                                        */
  54. /************************************************************************/
  55. void operator delete(void *ptr)
  56. {
  57.     if(ptr) DisposPtr((Ptr)ptr);
  58. }
  59.  
  60. #else
  61.  
  62. typedef struct FreeMemList {
  63.     struct FreeMemList    *next;
  64.     long                size;
  65. }    FreeMemList;
  66.  
  67. static FreeMemList    memlist;                //    dummy header block (always empty)
  68. static size_t _newpoolsize    = 0x00010000L;    //    number of bytes allocated for a new pool
  69. static size_t _newnonptrmax    = 0x00001000L;    //    any object bigger than this will call NewPtr(...) directly 
  70.  
  71. /************************************************************************/
  72. /*    Purpose..:     Set size of future allocation pools                        */
  73. /*    Input....:    size of future allocation pools                            */
  74. /*    Return...:    ---                                                        */
  75. /************************************************************************/
  76. void _set_newpoolsize(size_t size)
  77. {
  78.     _newpoolsize=size;
  79. }
  80.  
  81. /************************************************************************/
  82. /*    Purpose..:     Set NewPtr(...) pointer threshold                        */
  83. /*    Input....:    size of new threshold                                    */
  84. /*    Return...:    ---                                                        */
  85. /************************************************************************/
  86. void _set_newnonptrmax(size_t size)
  87. {
  88.     _newnonptrmax=size;
  89. }
  90.  
  91. /************************************************************************/
  92. /*    Purpose..:     Preallocate an allocation pool                            */
  93. /*    Input....:    size of pool to allocate                                */
  94. /*    Return...:    1: no error; 0:    fail                                    */
  95. /************************************************************************/
  96. char _prealloc_newpool(size_t size)
  97. {
  98.     FreeMemList    *list;
  99.  
  100.     if((list=(FreeMemList *)NewPtr(size))==NULL) return 0;
  101.     list->next=memlist.next; list->size=size; memlist.next=list;
  102.     return 1;
  103. }
  104.  
  105. /************************************************************************/
  106. /*    Purpose..:     Allocate memory                                            */
  107. /*    Input....:    size of memory to allocate                                */
  108. /*    Return...:    pointer to memory or 0L                                    */
  109. /************************************************************************/
  110. void *operator new(size_t size)
  111. {
  112.     Ptr ptr;
  113.  
  114.     size=(size&0xFFFFFFFC)+8;        //    alloc *4 quantity plus 4 extra bytes for size
  115.  
  116.     if(size>=_newnonptrmax)
  117.     {    //    try to get pointer from OS
  118.         while(1)
  119.         {
  120.             if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
  121.             if(new_handler) new_handler(); else return(NULL);
  122.         }            
  123.     }
  124.  
  125.     while(1)
  126.     {
  127.         FreeMemList    *list,*prev;
  128.  
  129.         for(prev=&memlist,list=prev->next; list; prev=list,list=list->next) if(size<=list->size)
  130.         {
  131. alloc:        if(list->size>=size+sizeof(FreeMemList))
  132.             {    //    split this free block
  133.                 list->size-=size; ptr=(Ptr)list+list->size;
  134.                 *(long *)ptr=size; return(ptr+4);
  135.             }
  136.             //    remove this block from list
  137.             prev->next=list->next; *(long *)list=list->size; return((Ptr)list+4);
  138.         }
  139.     
  140.         //    not enough free memory in memlist (try to allocate a new Ptr from OS
  141.         if((list=(FreeMemList *)NewPtr(_newpoolsize))==NULL)
  142.         {
  143.             if(new_handler) new_handler(); else return(NULL);
  144.         }
  145.         else
  146.         {
  147.             list->next=memlist.next; list->size=_newpoolsize;
  148.             memlist.next=list; prev=&memlist; goto alloc;
  149.         }
  150.     }
  151. }
  152.  
  153. /************************************************************************/
  154. /*    Purpose..:     Dispose memory                                            */
  155. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  156. /*    Return...:    ---                                                        */
  157. /************************************************************************/
  158. void operator delete(void *ptr)
  159. {
  160.     if(ptr)
  161.     {
  162.         long size;
  163.  
  164.         ptr=(Ptr)ptr-4; size=*(long *)ptr;
  165.         if(size!=-1L)
  166.         {
  167.             FreeMemList    *list,*prev;
  168.  
  169.             for(prev=&memlist,list=prev->next; list; prev=list,list=list->next)
  170.             {
  171.                 if((Ptr)ptr+size==(Ptr)list)
  172.                 {    //    merge block in front of this list item
  173.                     prev->next=list->next; size+=list->size; list=prev; continue;
  174.                 }
  175.                 if((Ptr)ptr==(Ptr)list+list->size)
  176.                 {    //    merge block at the end of this list item
  177.                     prev->next=list->next; ptr=list; size+=list->size; list=prev; continue;
  178.                 }
  179.             }
  180.         
  181.             list=(FreeMemList *)ptr; list->next=memlist.next; list->size=size; memlist.next=list;
  182.         }
  183.         else DisposPtr((Ptr)ptr);
  184.     }
  185. }
  186.  
  187. #endif
  188.  
  189. /************************************************************************/
  190. /*    Purpose..:     Allocate memory    (handle)                                */
  191. /*    Input....:    size of memory to allocate                                */
  192. /*    Return...:    handle to memory or 0L                                    */
  193. /************************************************************************/
  194. void *__new_hdl(size_t size)
  195. {
  196.     void *ptr;
  197.  
  198.     while((ptr=NewHandle(size))==NULL)
  199.     {
  200.         if(new_handler) new_handler(); else return(NULL);
  201.     }
  202.     return(ptr);
  203. }
  204.  
  205. /************************************************************************/
  206. /*    Purpose..:     Dispose memory (handle)                                    */
  207. /*    Input....:    handle to memory or 0L (no action if 0L)                */
  208. /*    Return...:    ---                                                        */
  209. /************************************************************************/
  210. void __del_hdl(void *hdl)
  211. {
  212.     if(hdl) DisposHandle((Handle)hdl);
  213. }
  214.